package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.commons.utils.AnimalsUtils;
import com.tanhua.dubbo.api.SoulPaperApi;
import com.tanhua.dubbo.api.SoulReportApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.db.Options;
import com.tanhua.model.db.Questions;
import com.tanhua.model.db.SoulPaper;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Answer;
import com.tanhua.model.mongo.UserReport;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SoulPaperService {

    @DubboReference
    private SoulPaperApi soulPaperApi;
    @DubboReference
    private SoulReportApi soulReportApi;
    @DubboReference
    private UserInfoApi userInfoApi;

    //查询问卷表
    public List<SoulPaperVo> findSoul() {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //1.查询问卷表
        List<SoulPaper> list = soulPaperApi.findSoul();
        //2.对问卷表进行组装返回
        List<SoulPaperVo> vos = new ArrayList<>();
        //获取到全部问题，问题中携带的是选项的vo对象
        List<Questions> questionsList = findQuestions();
        //创建一个空集合
        List<QuestionsVo> questionsVos = new ArrayList<>();
        //循环构建，每一个questions对象构建一个questionsVo对象
        for (Questions questions : questionsList) {
            QuestionsVo vo = QuestionsVo.init(questions);
            //添加到对应的questionVos集合
            questionsVos.add(vo);
        }

        //3.循环查询到SoulPaper集合，一个SoulPaper构建一个vo;
        for (SoulPaper soulPaper : list) {
            SoulPaperVo vo = SoulPaperVo.init(soulPaper);
            //4将soulPaper的id设置给vo对象
            Long id = soulPaper.getId();
            vo.setId(id.toString());
            //5.将soulPaper的difficulty字段赋值给vo的level字段
            vo.setLevel(soulPaper.getDifficulty());
            //6.根据当前用户id去用户答卷表里边查询，如果有数据就将主键id设置到vo里
            UserReport userReport = soulReportApi.findByIds(userId);
            if (userReport != null) {
                vo.setReportId(userReport.getId().toString());
                //打开锁
                vo.setIsLock(0);

            }
            //7.判断一下vo的星级
            if (soulPaper.getStar() == 1) {
                //8.如果难度1颗星的时候，将答卷解锁
                vo.setIsLock(0);
            }

            //9.查询到问题集合当中，所有答卷id等于当前答卷id的对象集合
            List<Questions> questions = questionsList.stream().filter(questions1 -> questions1.getSoulid().equals(id)).collect(Collectors.toList());
            //10.从这里获取到所有主键id
            List<Long> ids = CollUtil.getFieldValues(questions, "id", Long.class);
            List<QuestionsVo> questVo = questionsVos.stream().filter(questionsVo -> CollUtil.contains(ids, Long.valueOf(questionsVo.getId()))).collect(Collectors.toList());
            //11.将问题集合设置到vo中
            vo.setQuestions(questVo);
            //12.将vo添加到集合当中
            vos.add(vo);
        }
        //13.返回集合
        return vos;
    }

    //查询题目表，Controller层没有对应的方法,Service自身调用的
    private List<Questions> findQuestions() {
        //1.查询题目表
        List<Questions> questionsList = soulPaperApi.findQuestions();
        //2.查询问题选项表，这里实际返回一个OptionsVo对象的集合
        List<Options> optionsList = soulPaperApi.findOptions();
        //3.创建一个空的选项vo集合
        List<OptionsVo> vos = new ArrayList<>();
        //4.循环选项集合
        for (Options options : optionsList) {
            OptionsVo vo = OptionsVo.init(options);
            vos.add(vo);
        }
        List<OptionsVo> voss = new ArrayList<>();

        //5.循环问题构建
        for (Questions questions : questionsList) {
            //6.获取到问题id
            Long id = questions.getId();
            /*
            7.根据题目id获取到对应的题目
            jdk8的新特性，lambda表达式获取到optionsList集合中，所有题目id等于当前题目id的选项，并以集合形式返回
            */
            List<Options> optionss = optionsList
                    .stream()
                    .filter(options -> options.getQuestionId().equals(id))
                    .collect(Collectors.toList());
            //8.获取到所有的主键
            List<Long> ids = CollUtil.getFieldValues(optionss, "id", Long.class);
            //9.循环vos,判断每一个vo的主键是否在ids中，如果存在就将该vo添加到集合当中
            List<OptionsVo> opVos = vos.stream().filter(optionsVo -> CollUtil.contains(ids, Long.valueOf(optionsVo.getId()))).collect(Collectors.toList());
            //11.将剩余符合要求的选项设置到问题对象当中
            questions.setOptions(opVos);
        }
        return questionsList;
    }

    //计算评分，生成报告
    public String submitTheAnswer(List<Answer> answerList) {
        //1.获取当前用户id
        Long userId = UserHolder.getUserId();
        //2.从list中获取到两个编号
        List<Long> optionIds = CollUtil.getFieldValues(answerList, "optionId", Long.class);
        //3.获取到试卷id,因为做的是一套试卷，所以试卷id是重复的，且都为同一个
        List<Long> questionIds = CollUtil.getFieldValues(answerList, "questionId", Long.class);
        Long soulPaperId = questionIds.get(1);
        //3.调用api查询
        UserReport report = soulPaperApi.findReport(optionIds, soulPaperId, userId);
        //4.将数据保存到mongo
        soulReportApi.save(report);
        //5.根据当前用户id查询一次,表中有且只有一条答卷数据
        UserReport userReport = soulReportApi.findByIds(userId);
        String reportId = userReport.getId().toString();
        //5.返回id
        return reportId;
    }

    //查看生成的报告id
    public ReportVo findReport(String reportId) {
        //1.前端传递了一个答卷id,需要根据答卷id查询出一个UserReport对象
        UserReport userReport = soulReportApi.findByReportId(reportId);
        //2.查询一下当前用户的答卷的类型（比如是狮子，兔子什么的）
        String genre = userReport.getGenre();
        //3.根据类型查询出一个集合
        List<UserReport> list = soulReportApi.findList(genre);
        //4.从这个集合中获取到所有的userId;
        List<Long> ids = CollUtil.getFieldValues(list, "userId", Long.class);
        //5.根据ids查询出对应的userInfo集合
        List<UserInfo> userInfos = userInfoApi.findList(ids);
        //6.调用init方法构造
        ReportVo vo = ReportVo.init(userReport, userInfos,UserHolder.getUserId());
        //7.添加dimensions属性
        Dimensions[] dimensions = new Dimensions[4];
        //8.判断用户所属的人格

        if (userReport.getGenre().equals(AnimalsUtils.ANIMAL_OWL)) {
            //猫头鹰
            dimensions[0] = new Dimensions("外向","30%");
            dimensions[1] = new Dimensions("判断","70%");
            dimensions[2] = new Dimensions("抽象","60%");
            dimensions[3] = new Dimensions("理性","90%");
        } else if (userReport.getGenre().equals(AnimalsUtils.ANIMAL_FOX)) {
            //狐狸
            dimensions[0] = new Dimensions("外向","80%");
            dimensions[1] = new Dimensions("判断","60%");
            dimensions[2] = new Dimensions("抽象","20%");
            dimensions[3] = new Dimensions("理性","40%");
        } else if (userReport.getGenre().equals(AnimalsUtils.ANIMAL_RABBIT)) {
            //兔子
            dimensions[0] = new Dimensions("外向", "10%");
            dimensions[1] = new Dimensions("判断", "80%");
            dimensions[2] = new Dimensions("抽象", "30%");
            dimensions[3] = new Dimensions("理性", "95%");
        } else {
            //狮子
            dimensions[0] = new Dimensions("外向", "100%");
            dimensions[1] = new Dimensions("判断", "20%");
            dimensions[2] = new Dimensions("抽象", "10%");
            dimensions[3] = new Dimensions("理性", "50%");
        }
        //9.设置值
        vo.setDimensions(dimensions);
        //10.返回
        return vo;
    }
}
